package com.xp.ai.tools;

import com.xp.ai.util.ModelUtils;
import dev.langchain4j.agent.tool.*;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ChatRequestBuilder;
import dev.langchain4j.model.chat.request.ChatRequestParameters;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.service.tool.DefaultToolExecutor;
import dev.langchain4j.service.tool.ToolExecution;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 *
 *
 *  本地方法增强大模型
 */
public class WithToolsChat2 {

    static class Tools{
        @Tool("当前日期")
        //因为要在 static 中调用 ，所以这里得是 static 得 不然找不到会报错得
        public static String now(){
            return LocalDateTime.now().toString();
        }

        @Tool("获取某个城市的天气情况")
        public String  getWeather(@P("指定的城市")String location){
            return location + "的天气是晴天";
        }
    }

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

//        ChatLanguageModel chatModel = ModelUtils.getDeepSeeV3Model();
        ChatLanguageModel chatModel = ModelUtils.getHuoshanv3Model();

        List<ChatMessage> chatMessages = new ArrayList<>(4);

        //构建用户消息
        UserMessage userMessage = UserMessage.from("成都今天的天气怎么样？");
        chatMessages.add(userMessage);

        //构建工具类
        List<ToolSpecification> toolSpecifications = ToolSpecifications.toolSpecificationsFrom(Tools.class);
        //构建请求参数
        ChatRequestParameters chatRequestParameters1 = ChatRequestParameters.builder()
                .toolSpecifications(toolSpecifications)
                .build();
        //构建请求
        ChatRequest chatRequest1 = ChatRequest.builder()
                .messages(chatMessages)
                .parameters(chatRequestParameters1)
                .build();
        //第一次对话
        ChatResponse chatResponse1 = chatModel.chat(chatRequest1);

        //获取大模型返回消息
        AiMessage aiMessage = chatResponse1.aiMessage();
        System.out.println(aiMessage);

        //查看是否需要调用工具增强
        if (aiMessage.hasToolExecutionRequests()) {
            //获取即将调用的增强工具
            List<ToolExecutionRequest> toolExecutionRequests = aiMessage.toolExecutionRequests();
            for (ToolExecutionRequest toolExecutionRequest : toolExecutionRequests) {
                String name = toolExecutionRequest.name();
                String arguments = toolExecutionRequest.arguments();
                System.out.println(" 调用的方法 ："+name);
                System.out.println(" 调用的参数 ："+arguments);
            }
            //将大模型的返回加入消息体
            chatMessages.add(aiMessage);

            Tools tools =  new Tools();
            toolExecutionRequests.forEach(toolExecutionRequest -> {
                //构建默认的工具执行器
                DefaultToolExecutor toolExecutor = new DefaultToolExecutor(tools,toolExecutionRequest);
                //执行对应的工具中的方法 ###### 重点： 这里就不在需要调用反射什么的了直接调用这段话
                String res = toolExecutor.execute(toolExecutionRequest, UUID.randomUUID().toString());
                System.out.println("工具执行结果:"+res);
                //构建工具消息
                ToolExecutionResultMessage toolExecutionResultMessage = ToolExecutionResultMessage.from(toolExecutionRequest.id(), toolExecutionRequest.name(), res);
                //将工具消息加入到消息体中
                chatMessages.add(toolExecutionResultMessage);
            });

            //得到工具的消息之后再次对话
            ChatRequestParameters chatRequestParameters2 = ChatRequestParameters.builder()
                    .toolSpecifications(toolSpecifications)
                    .build();
            ChatRequest chatRequest = ChatRequest.builder()
                    .parameters(chatRequestParameters2)
                    .messages(chatMessages)
                    .build();

            //最终的消息
            ChatResponse finalResponse = chatModel.chat(chatRequest);
            String text = finalResponse.aiMessage().text();
            System.out.println(text);

        }



    }
}
